home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / trap.c < prev    next >
C/C++ Source or Header  |  1993-01-24  |  62KB  |  2,521 lines

  1. /*    SCCS Id: @(#)trap.c    3.1    92/12/10    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6.  
  7. #ifdef OVLB
  8. const char *traps[TRAPNUM] = {
  9.     "",
  10.     "n arrow trap",
  11.     " dart trap",
  12.     " falling rock trap",
  13.     " squeaky board",
  14.     " bear trap",
  15.     " land mine",
  16.     " sleeping gas trap",
  17.     " rust trap",
  18.     " fire trap",
  19.     " pit",
  20.     " spiked pit",
  21.     " trapdoor",
  22.     " teleportation trap",
  23.     " level teleporter",
  24.     " magic portal",
  25.     " web",
  26.     " statue trap",
  27.     " magic trap",
  28.     "n anti-magic field"
  29. #ifdef POLYSELF
  30.     ," polymorph trap"
  31. #endif
  32. };
  33.  
  34. #endif /* OVLB */
  35.  
  36. static void FDECL(domagicportal,(struct trap *));
  37. static void NDECL(dofiretrap);
  38. static void NDECL(domagictrap);
  39. static boolean FDECL(emergency_disrobe,(boolean *));
  40. STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int));
  41.  
  42. #ifdef OVLB
  43.  
  44. static int FDECL(teleok, (int,int,BOOLEAN_P));
  45. static void NDECL(vtele);
  46. static void FDECL(no_fall_through, (BOOLEAN_P));
  47.  
  48. /* Generic rust-armor function.  Returns TRUE if a message was printed;
  49.  * "print", if set, means to print a message (and thus to return TRUE) even
  50.  * if the item could not be rusted; otherwise a message is printed and TRUE is
  51.  * returned only for rustable items.
  52.  */
  53. boolean
  54. rust_dmg(otmp, ostr, type, print)
  55. register struct obj *otmp;
  56. register const char *ostr;
  57. int type;
  58. boolean print;
  59. {
  60.     static const char NEARDATA *action[] = { "smoulder", "rust", "rot", "corrode" };
  61.     static const char NEARDATA *msg[] =  { "burnt", "rusted", "rotten", "corroded" };
  62.     boolean vulnerable = FALSE;
  63.     boolean plural;
  64.     boolean grprot = FALSE;
  65.  
  66.     if (!otmp) return(FALSE);
  67.     switch(type) {
  68.         case 0:
  69.         case 2: vulnerable = is_flammable(otmp); break;
  70.         case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break;
  71.         case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break;
  72.     }
  73.  
  74.     if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE))
  75.         return FALSE;
  76.  
  77.     plural = is_gloves(otmp) || is_boots(otmp);
  78.  
  79.     if (!vulnerable)
  80.         if (flags.verbose)
  81.             Your("%s %s not affected.", ostr, plural ? "are" : "is");
  82.     else if (otmp->oeroded < MAX_ERODE) {
  83.         if (grprot && otmp->greased)
  84.             grease_protect(otmp,ostr,plural);
  85.         else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
  86.             if (flags.verbose)
  87.                 pline("Somehow, your %s %s not affected.",
  88.                     ostr, plural ? "are" : "is");
  89.         } else {
  90.             Your("%s %s%s%s!", ostr, action[type],
  91.                 plural ? "" : "s",
  92.                     otmp->oeroded+1 == MAX_ERODE ? " completely" :
  93.                 otmp->oeroded ? " further" : "");
  94.             otmp->oeroded++;
  95.         }
  96.     } else
  97.         if (flags.verbose)
  98.             Your("%s %s%s completely %s.", ostr,
  99.                  Blind ? "feel" : "look",
  100.                  plural ? "" : "s", msg[type]);
  101.     return(TRUE);
  102. }
  103.  
  104. void
  105. grease_protect(otmp,ostr,plu)
  106. register struct obj *otmp;
  107. register const char *ostr;
  108. register boolean plu;
  109. {
  110.     static const char txt[] = "protected by the layer of grease!";
  111.  
  112.     if (ostr)
  113.         Your("%s %s %s",ostr,plu ? "are" : "is",txt);
  114.     else
  115.         Your("%s %s",aobjnam(otmp,"are"),txt);
  116.     if (!rn2(2)) {
  117.         pline("The grease dissolves.");
  118.         otmp->greased = 0;
  119.     }
  120. }
  121.  
  122. struct trap *
  123. maketrap(x,y,typ)
  124. register int x, y, typ;
  125. {
  126.     register struct trap *ttmp;
  127.     register boolean oldplace;
  128.  
  129.     if (ttmp = t_at(x,y)) {
  130.         oldplace = TRUE;
  131.         if (u.utrap && (x == u.ux) && (y == u.uy) && 
  132.           ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) ||
  133.           (u.utraptype == TT_WEB && typ != WEB) ||
  134.           (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT)))
  135.             u.utrap = 0;
  136.     } else {
  137.         oldplace = FALSE;
  138.         ttmp = newtrap();
  139.         ttmp->tx = x;
  140.         ttmp->ty = y;
  141.     }
  142.     ttmp->ttyp = typ;
  143.     switch(typ) {
  144.         case STATUE_TRAP:        /* create a "living" statue */
  145.         (void) mkcorpstat(STATUE, &mons[rndmonnum()], x, y, FALSE);
  146.         break;
  147.         case PIT:
  148.         case SPIKED_PIT:
  149.         case TRAPDOOR:
  150.         levl[x][y].doormask = 0;   /* subsumes altarmask, icedpool... */
  151.         if (IS_ROOM(levl[x][y].typ))
  152.             levl[x][y].typ = ROOM;
  153.         break;
  154.     }
  155.     ttmp->tseen = 0;
  156.     ttmp->once = 0;
  157.     ttmp->dst.dnum = -1;
  158.     ttmp->dst.dlevel = -1;
  159.     if (!oldplace) {
  160.         ttmp->ntrap = ftrap;
  161.         ftrap = ttmp;
  162.     }
  163.     return(ttmp);
  164. }
  165.  
  166. static int
  167. teleok(x, y, trapok)
  168. register int x, y;
  169. boolean trapok;
  170. {                /* might throw him into a POOL
  171.                  * removed by GAN 10/20/86
  172.                  */
  173. #ifdef STUPID
  174.     boolean    tmp1, tmp2, tmp3, tmp4;
  175. # ifdef POLYSELF
  176.     tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||
  177.         passes_walls(uasmon)) && !MON_AT(x, y);
  178. # else
  179.     tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y);
  180. # endif
  181.     tmp2 = !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y));
  182.     tmp3 = !(is_pool(x,y) &&
  183.            !(Levitation || Wwalking || Magical_breathing
  184. # ifdef POLYSELF
  185.          || is_flyer(uasmon) || is_swimmer(uasmon)
  186.          || is_clinger(uasmon)
  187. # endif
  188.         )) && !closed_door(x,y);
  189.     tmp4 = !is_lava(x,y);
  190.     return(tmp1 && tmp2 && tmp3 && tmp4);
  191. #else
  192.     return( isok(x,y) &&
  193. # ifdef POLYSELF
  194.         (!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&
  195. # else
  196.         !IS_ROCK(levl[x][y].typ) &&
  197. # endif
  198.         !MON_AT(x, y) &&
  199.         !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y)) &&
  200.         !(is_pool(x,y) &&
  201.         !(Levitation || Wwalking || Magical_breathing
  202. # ifdef POLYSELF
  203.           || is_flyer(uasmon) || is_swimmer(uasmon)
  204.           || is_clinger(uasmon)
  205. # endif
  206.           )) && !is_lava(x,y) && !closed_door(x,y));
  207. #endif
  208.     /* Note: gold is permitted (because of vaults) */
  209. }
  210.  
  211. boolean
  212. safe_teleds()
  213. {
  214.     register int nux, nuy;
  215.     short tcnt = 0;
  216.  
  217.     do {
  218.         nux = rnd(COLNO-1);
  219.         nuy = rn2(ROWNO);
  220.     } while (!teleok(nux, nuy, tcnt>200) && tcnt++ < 400);
  221.  
  222.     if (tcnt < 400) {
  223.         teleds(nux, nuy);
  224.         return TRUE;
  225.     } else
  226.         return FALSE;
  227. }
  228.  
  229. static void
  230. vtele()
  231. {
  232.     register struct mkroom *croom = search_special(VAULT);
  233.     coord c;
  234.  
  235.     if(croom && somexy(croom, &c) && teleok(c.x,c.y,FALSE)) {
  236.         teleds(c.x,c.y);
  237.         return;
  238.     }
  239.     tele();
  240. }
  241.  
  242. static void
  243. no_fall_through(td)
  244. boolean td;
  245. {
  246.     /* floor objects get a chance of falling down.  the case
  247.      * where the hero does NOT fall down is treated here.  the
  248.      * case where the hero does fall down is treated in goto_level().
  249.      * reason: the target level of the fall is not determined here,
  250.      * and it need not be the next level.  if we want falling
  251.      * objects to arrive near the player, we must call impact_drop()
  252.      * _after_ the target level is determined.
  253.      */
  254.     impact_drop((struct obj *)0, u.ux, u.uy, 0);
  255.     if (!td) {
  256.         display_nhwindow(WIN_MESSAGE, FALSE);
  257.         pline("The opening under you closes up.");
  258.     }
  259. }
  260.  
  261. void
  262. fall_through(td)
  263. boolean td;    /* td == TRUE : trapdoor */
  264. {
  265.     register int newlevel = dunlev(&u.uz);
  266.  
  267.     if(Blind && Levitation) return;
  268.  
  269.     do {
  270.         newlevel++;
  271.     } while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz));
  272.  
  273.     if(td) pline("A trap door opens up under you!");
  274.     else pline("The floor opens up under you!");
  275.  
  276.     if(Levitation || u.ustuck || !Can_fall_thru(&u.uz)
  277. #ifdef POLYSELF
  278.        || is_flyer(uasmon) || is_clinger(uasmon)
  279. #endif
  280.        || (Inhell && !u.uevent.invoked &&
  281.                     newlevel == dunlevs_in_dungeon(&u.uz))
  282.         ) {
  283.             You("don't fall in.");
  284.             no_fall_through(td);
  285.             return;
  286.     }
  287. #ifdef WALKIES
  288.     if(!next_to_u()) {
  289.         You("are jerked back by your pet!");
  290.         no_fall_through(td);
  291.         return;
  292.     }
  293. #endif
  294.     if(*u.ushops) shopdig(1);
  295.     if(Is_stronghold(&u.uz)) goto_hell(TRUE, TRUE);
  296.     else {
  297.         d_level    dtmp;
  298.         dtmp.dnum = u.uz.dnum;
  299.         dtmp.dlevel = newlevel;
  300.         goto_level(&dtmp, FALSE, TRUE, FALSE);
  301.         if(!td) pline("The hole in the ceiling above you closes up.");
  302.     }
  303. }
  304.  
  305. void
  306. dotrap(trap)
  307. register struct trap *trap;
  308. {
  309.     register int ttype = trap->ttyp;
  310.     register struct monst *mtmp;
  311.     register struct obj *otmp;
  312.  
  313.     nomul(0);
  314.     if(trap->tseen && !Fumbling &&
  315. #ifdef POLYSELF
  316.        !((ttype == PIT || ttype == SPIKED_PIT) && !is_clinger(uasmon)) &&
  317. #else
  318.        !(ttype == PIT || ttype == SPIKED_PIT) &&
  319. #endif
  320.        !(ttype == MAGIC_PORTAL || ttype == ANTI_MAGIC) && !rn2(5))
  321.         You("escape a%s.", traps[ttype]);
  322.     else {
  323.         seetrap(trap);
  324.         switch(ttype) {
  325.         case ARROW_TRAP:
  326.             pline("An arrow shoots out at you!");
  327.             otmp = mksobj(ARROW, TRUE, FALSE);
  328.             otmp->quan = 1L;
  329.             otmp->owt = weight(otmp);
  330.             if(thitu(8,dmgval(otmp,uasmon),otmp,"arrow"))
  331.             obfree(otmp, (struct obj *)0);
  332.             else {
  333.             place_object(otmp, u.ux, u.uy);
  334.             otmp->nobj = fobj;
  335.             fobj = otmp;        
  336.             stackobj(otmp);
  337.             newsym(u.ux, u.uy);
  338.             }
  339.             break;
  340.         case DART_TRAP:
  341.             pline("A little dart shoots out at you!");
  342.             otmp = mksobj(DART, TRUE, FALSE);
  343.             otmp->quan = 1L;
  344.             otmp->owt = weight(otmp);
  345.             if (!rn2(6)) otmp->opoisoned = 1;
  346.             if(thitu(7,dmgval(otmp,uasmon),otmp,"little dart")) {
  347.             if (otmp->opoisoned)
  348.                 poisoned("dart",A_CON,"poison dart",10);
  349.             obfree(otmp, (struct obj *)0);
  350.             } else {
  351.             place_object(otmp, u.ux, u.uy);
  352.             otmp->nobj = fobj;
  353.             fobj = otmp;        
  354.             stackobj(otmp);
  355.             newsym(u.ux, u.uy);
  356.             }
  357.             break;
  358.         case ROCKTRAP:
  359.             {
  360.             int dmg = d(2,6); /* should be std ROCK dmg? */
  361.  
  362.             otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE);
  363.             otmp->quan = 1L;
  364.             otmp->owt = weight(otmp);
  365.  
  366.     pline("A trap door in the ceiling opens and a rock falls on your %s!",
  367.                 body_part(HEAD));
  368.  
  369.             if (uarmh)
  370.                 if(is_metallic(uarmh)) {
  371.                 pline("Fortunately, you are wearing a hard helmet.");
  372.                 dmg = 2;
  373.                 } else if (flags.verbose)
  374.                  Your("%s does not protect you.", xname(uarmh));
  375.  
  376.             stackobj(otmp);
  377.             newsym(u.ux,u.uy);    /* map the rock */
  378.  
  379.             losehp(dmg, "falling rock", KILLED_BY_AN);
  380.             exercise(A_STR, FALSE);
  381.             }
  382.             break;
  383.  
  384.         case SQKY_BOARD:        /* stepped on a squeaky board */
  385.             if (Levitation
  386. #ifdef POLYSELF
  387.             || is_flyer(uasmon) || is_clinger(uasmon)
  388. #endif
  389.             ) {
  390.             if (Hallucination) You("notice a crease in the linoleum.");
  391.             else You("notice a loose board below you.");
  392.             } else {
  393.             pline("A board beneath you squeaks loudly.");
  394.             wake_nearby();
  395.             }
  396.             break;
  397.  
  398.         case BEAR_TRAP:
  399.             if(Levitation
  400. #ifdef POLYSELF
  401.                 || is_flyer(uasmon)) {
  402.             You("%s over a bear trap.",
  403.                   Levitation ? "float" : "fly");
  404. #else
  405.                 ) {
  406.             You("float over a bear trap.");
  407. #endif
  408.             break;
  409.             }
  410. #ifdef POLYSELF
  411.             if(amorphous(uasmon)) {
  412.             pline("A bear trap closes harmlessly through you.");
  413.             break;
  414.             }
  415. #endif
  416.             u.utrap = rn1(4, 4);
  417.             u.utraptype = TT_BEARTRAP;
  418.             pline("A bear trap closes on your %s!",
  419.             body_part(FOOT));
  420. #ifdef POLYSELF
  421.             if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
  422.             You("howl in anger!");
  423. #endif
  424.             exercise(A_DEX, FALSE);
  425.             break;
  426.  
  427.         case SLP_GAS_TRAP:
  428.             if(Sleep_resistance) {
  429.             You("are enveloped in a cloud of gas!");
  430.             break;
  431.             }
  432.             pline("A cloud of gas puts you to sleep!");
  433.             flags.soundok = 0;
  434.             nomul(-rnd(25));
  435.             u.usleep = 1;
  436.             nomovemsg = "You wake up.";
  437.             afternmv = Hear_again;
  438.             break;
  439.  
  440.         case RUST_TRAP:
  441. #ifdef POLYSELF
  442.             if (u.umonnum == PM_IRON_GOLEM) {
  443.             pline("A gush of water hits you!");
  444.             You("are covered with rust!");
  445.             rehumanize();
  446.             break;
  447.             } else
  448.             if (u.umonnum == PM_GREMLIN && rn2(3)) {
  449.             pline("A gush of water hits you!");
  450.             if(mtmp = cloneu()) {
  451.                 mtmp->mhpmax = (u.mhmax /= 2);
  452.                 You("multiply.");
  453.             }
  454.             break;
  455.             }
  456. #endif
  457.         /* Unlike monsters, traps cannot aim their rust attacks at
  458.          * you, so instead of looping through and taking either the
  459.          * first rustable one or the body, we take whatever we get,
  460.          * even if it is not rustable.
  461.          */
  462.             switch (rn2(5)) {
  463.             case 0:
  464.                 pline("A gush of water hits you on the %s!",
  465.                     body_part(HEAD));
  466.                 (void) rust_dmg(uarmh, "helmet", 1, TRUE);
  467.                 break;
  468.             case 1:
  469.                 pline("A gush of water hits your left %s!",
  470.                     body_part(ARM));
  471.                 if (rust_dmg(uarms, "shield", 1, TRUE)) break;
  472.                 if (uwep && bimanual(uwep))
  473.                 goto two_hand;
  474.                 /* Two goto statements in a row--aaarrrgggh! */
  475. glovecheck:            (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
  476.                 /* Not "metal gauntlets" since it gets called
  477.                  * even if it's leather for the message
  478.                  */
  479.                 break;
  480.             case 2:
  481.                 pline("A gush of water hits your right %s!",
  482.                     body_part(ARM));
  483. two_hand:            erode_weapon(FALSE);
  484.                 goto glovecheck;
  485.             default:
  486.                 pline("A gush of water hits you!");
  487.                 if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE);
  488.                 else if (uarm)
  489.                 (void) rust_dmg(uarm, "armor", 1, TRUE);
  490. #ifdef TOURIST
  491.                 else if (uarmu)
  492.                 (void) rust_dmg(uarmu, "shirt", 1, TRUE);
  493. #endif
  494.             }
  495.             break;
  496.  
  497.                 case FIRE_TRAP:
  498.                 dofiretrap();
  499.                 break;
  500.  
  501.         case PIT:
  502.             if (Levitation
  503. #ifdef POLYSELF
  504.             || is_flyer(uasmon) || is_clinger(uasmon)
  505. #endif
  506.             ) {
  507.             if(Blind) break;
  508.             if(trap->tseen)
  509.                 You("see a pit below you.");
  510.             else {
  511.                 pline("A pit opens up under you!");
  512.                 You("don't fall in!");
  513.             }
  514.             break;
  515.             }
  516.             You("fall into a pit!");
  517. #ifdef POLYSELF
  518.             if (!passes_walls(uasmon))
  519. #endif
  520.             u.utrap = rn1(6,2);
  521.             u.utraptype = TT_PIT;
  522.             losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX);
  523.             if (Punished && !carried(uball)) {
  524.             unplacebc();
  525.             ballfall();
  526.             placebc();
  527.             }
  528.             selftouch("Falling, you");
  529.             exercise(A_STR, FALSE);
  530.             vision_full_recalc = 1;    /* vision limits change */
  531.             break;
  532.         case SPIKED_PIT:
  533.             if (Levitation
  534. #ifdef POLYSELF
  535.             || is_flyer(uasmon) || is_clinger(uasmon)
  536. #endif
  537.             ) {
  538.             if(Blind) break;
  539.             pline("A pit full of spikes opens up under you!");
  540.             You("don't fall in!");
  541.             break;
  542.             }
  543.             You("fall into a pit!");
  544.             You("land on a set of sharp iron spikes!");
  545. #ifdef POLYSELF
  546.             if (!passes_walls(uasmon))
  547. #endif
  548.             u.utrap = rn1(6,2);
  549.             u.utraptype = TT_PIT;
  550.             losehp(rnd(10),"fell into a pit of iron spikes",
  551.             NO_KILLER_PREFIX);
  552.             if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8);
  553.             if (Punished && !carried(uball)) {
  554.             unplacebc();
  555.             ballfall();
  556.             placebc();
  557.             }
  558.             selftouch("Falling, you");
  559.             vision_full_recalc = 1;    /* vision limits change */
  560.             exercise(A_STR, FALSE);
  561.             exercise(A_DEX, FALSE);
  562.             break;
  563.  
  564.         case TRAPDOOR:
  565.             if(!Can_fall_thru(&u.uz))
  566.             panic("Trapdoors cannot exist on this level.");
  567.             fall_through(TRUE);
  568.             break;
  569.  
  570.         case TELEP_TRAP:
  571.             if(In_endgame(&u.uz) || Antimagic) {
  572.             if(Antimagic)
  573.                 shieldeff(u.ux, u.uy);
  574.             You("feel a wrenching sensation.");
  575. #ifdef WALKIES
  576.             } else if(!next_to_u()) {
  577.                 You(shudder_for_moment);
  578. #endif
  579.             } else if(trap->once) {
  580.             deltrap(trap);
  581.             newsym(u.ux,u.uy);    /* get rid of trap symbol */
  582.             vtele();
  583.             } else
  584.             tele();
  585.             break;
  586.         case LEVEL_TELEP:
  587.             You("%s onto a level teleport trap!",
  588.               Levitation ? (const char *)"float" :
  589. #ifdef POLYSELF
  590.               locomotion(uasmon, "step"));
  591. #else
  592.               (const char *)"step");
  593. #endif
  594.             if(Antimagic) {
  595.             shieldeff(u.ux, u.uy);
  596.             }
  597.             if(Antimagic || In_endgame(&u.uz)) {
  598.             You("feel a wrenching sensation.");
  599.             break;
  600.             }
  601.             if(!Blind)
  602.                 You("are momentarily blinded by a flash of light.");
  603.             else
  604.             You("are momentarily disoriented.");
  605.             deltrap(trap);
  606.             newsym(u.ux,u.uy);    /* get rid of trap symbol */
  607.             level_tele();
  608.             break;
  609.  
  610.         case WEB: /* Our luckless player has stumbled into a web. */
  611. #ifdef POLYSELF
  612.             if (amorphous(uasmon)) {
  613.                 if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE)
  614.             {
  615.                 deltrap(trap);
  616.                 newsym(u.ux,u.uy);/* update position */
  617.                 You("dissolve a spider web.");
  618.                 break;
  619.             }
  620.             You("flow through a spider web.");
  621.             break;
  622.             }
  623.             if (uasmon->mlet == S_SPIDER) {
  624.             pline("There is a spider web here.");
  625.             break;
  626.             }
  627. #endif
  628.             You("%s into a spider web!",
  629.               Levitation ? (const char *)"float" :
  630. #ifdef POLYSELF
  631.               locomotion(uasmon, "stumble"));
  632. #else
  633.               (const char *)"stumble");
  634. #endif
  635.             u.utraptype = TT_WEB;
  636.  
  637.             /* Time stuck in the web depends on your strength. */
  638.             {
  639.             register int str = ACURR(A_STR);
  640.  
  641.             if (str == 3) u.utrap = rn1(6,6);
  642.             else if (str < 6) u.utrap = rn1(6,4);
  643.             else if (str < 9) u.utrap = rn1(4,4);
  644.             else if (str < 12) u.utrap = rn1(4,2);
  645.             else if (str < 15) u.utrap = rn1(2,2);
  646.             else if (str < 18) u.utrap = rnd(2);
  647.             else if (str < 69) u.utrap = 1;
  648.             else {
  649.             u.utrap = 0;
  650.             You("tear through the web!");
  651.             deltrap(trap);
  652.             newsym(u.ux,u.uy);    /* get rid of trap symbol */
  653.             }
  654.             }
  655.             break;
  656.  
  657.         case STATUE_TRAP:
  658.             deltrap(trap);
  659.             newsym(u.ux,u.uy);    /* get rid of trap symbol */
  660.             for(otmp=level.objects[u.ux][u.uy];
  661.                         otmp; otmp = otmp->nexthere)
  662.             if(otmp->otyp == STATUE)
  663.                 if(mtmp=makemon(&mons[otmp->corpsenm],u.ux,u.uy)) {
  664.                 pline("The statue comes to life!");
  665.                 /* mimic statues become seen mimics */
  666.                 if(mtmp->m_ap_type) seemimic(mtmp);
  667.                 delobj(otmp);
  668.                 break;
  669.                 }
  670.             break;
  671.  
  672.         case MAGIC_TRAP:        /* A magic trap. */
  673.             if (!rn2(30)) {
  674.             deltrap(trap);
  675.             newsym(u.ux,u.uy);    /* update position */
  676.             You("are caught in a magical explosion!");
  677.             losehp(rnd(10), "magical explosion", KILLED_BY_AN);
  678.             Your("body absorbs some of the magical energy!");
  679.             u.uen = (u.uenmax += 2);
  680.             } else domagictrap();
  681.             break;
  682.  
  683.         case ANTI_MAGIC:
  684.             if(Antimagic) {
  685.             shieldeff(u.ux, u.uy);
  686.             You("feel momentarily lethargic.");
  687.             } else drain_en(rnd((int)u.ulevel) + 1);
  688.             break;
  689.  
  690. #ifdef POLYSELF
  691.         case POLY_TRAP:
  692.             if(Antimagic) {
  693.             shieldeff(u.ux, u.uy);
  694.             You("feel momentarily different.");
  695.             /* Trap did nothing; don't remove it --KAA */
  696.             } else {
  697.             deltrap(trap);    /* delete trap before polymorph */
  698.             newsym(u.ux,u.uy);    /* get rid of trap symbol */
  699.             You("feel a change coming over you.");
  700.             polyself();
  701.             }
  702.             break;
  703. #endif
  704.  
  705.         case LANDMINE: {
  706.             if (Levitation
  707. #ifdef POLYSELF
  708.                     || is_flyer(uasmon)
  709. #endif
  710.                                 ) {
  711.             You("see a trigger in a pile of soil below you.");
  712.             if (rn2(3)) break;
  713.             pline("KAABLAMM!!!  The air currents set it off!");
  714.             } else {
  715.             pline("KAABLAMM!!!  You triggered a land mine!");
  716.             set_wounded_legs(LEFT_SIDE, rn1(35, 41));
  717.             set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
  718.             }
  719.             losehp(rnd(16), "land mine", KILLED_BY_AN);
  720.             /* wake everything on the level */
  721.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  722.             if(mtmp->msleep) mtmp->msleep = 0;
  723.             }
  724.             deltrap(t_at(u.ux, u.uy));    /* mines only explode once */
  725.             newsym(u.ux,u.uy);        /* get rid of trap symbol */
  726.           }
  727.             break;
  728.  
  729.                 case MAGIC_PORTAL:
  730. #ifdef WALKIES
  731.             if(!next_to_u())
  732.                 You(shudder_for_moment);
  733.             else
  734. #endif
  735.                 domagicportal(trap);
  736.                 break;
  737.  
  738.         default:
  739.             impossible("You hit a trap of type %u", trap->ttyp);
  740.         }
  741.     }
  742. }
  743.  
  744. #endif /* OVLB */
  745.  
  746. #ifdef WALKIES
  747.  
  748. STATIC_DCL boolean FDECL(teleport_pet, (struct monst *));
  749.  
  750. #ifdef OVLB
  751.  
  752. STATIC_OVL boolean
  753. teleport_pet(mtmp)
  754. register struct monst *mtmp;
  755. {
  756.     register struct obj *otmp;
  757.  
  758.     if(mtmp->mleashed) {
  759.         otmp = get_mleash(mtmp);
  760.         if(!otmp)
  761.         impossible("%s is leashed, without a leash.", Monnam(mtmp));
  762.         if(otmp->cursed) {
  763. # ifdef SOUNDS
  764.         yelp(mtmp);
  765. # endif
  766.         return FALSE;
  767.         } else {
  768.         Your("leash goes slack.");
  769.         m_unleash(mtmp);
  770.         return TRUE;
  771.         }
  772.     }
  773.     return TRUE;
  774. }
  775.  
  776. #endif /* OVLB */
  777.  
  778. #endif /* WALKIES */
  779.  
  780. #ifdef OVLB
  781.  
  782. void
  783. seetrap(trap)
  784.     register struct trap *trap;
  785. {
  786.     if(!trap->tseen) {
  787.         trap->tseen = 1;
  788.         newsym(trap->tx, trap->ty);
  789.     }
  790. }
  791.  
  792. #endif /* OVLB */
  793. #ifdef OVL1
  794.  
  795. int
  796. mintrap(mtmp)
  797. register struct monst *mtmp;
  798. {
  799.     register struct trap *trap = t_at(mtmp->mx, mtmp->my);
  800.     boolean trapkilled = FALSE, tdoor = FALSE;
  801.     struct permonst *mptr = mtmp->data;
  802.     struct obj *otmp;
  803.  
  804.     if(!trap) {
  805.         mtmp->mtrapped = 0;    /* perhaps teleported? */
  806.     } else if (mtmp->mtrapped) {    /* was in trap */
  807.         if(!rn2(40)) 
  808.             if (sobj_at(BOULDER, mtmp->mx, mtmp->my) && 
  809.                 ((trap->ttyp == PIT) || 
  810.                  (trap->ttyp == SPIKED_PIT))) {
  811.                 if (!rn2(2)) {
  812.                     mtmp->mtrapped = 0;
  813.                     fill_pit(mtmp->mx, mtmp->my);
  814.                 }
  815.             } else
  816.                 mtmp->mtrapped = 0;
  817.     } else {
  818.         register int tt = trap->ttyp;
  819.  
  820.         /* A bug fix for dumb messages by ab@unido.
  821.          */
  822.         int in_sight = canseemon(mtmp);
  823.  
  824.         if(mtmp->mtrapseen & (1 << tt)) {
  825.         /* it has been in such a trap - perhaps it escapes */
  826.         if(rn2(4)) return(0);
  827.         }
  828.         mtmp->mtrapseen |= (1 << tt);
  829.         switch (tt) {
  830.         case ARROW_TRAP:
  831.             otmp = mksobj(ARROW, TRUE, FALSE);
  832.             otmp->quan = 1L;
  833.             otmp->owt = weight(otmp);
  834.             if(in_sight) seetrap(trap);
  835.             if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE;
  836.             break;
  837.         case DART_TRAP:
  838.             otmp = mksobj(DART, TRUE, FALSE);
  839.             otmp->quan = 1L;
  840.             otmp->owt = weight(otmp);
  841.             if (!rn2(6)) otmp->opoisoned = 1;
  842.             if(in_sight) seetrap(trap);
  843.             if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE;
  844.             break;
  845.         case ROCKTRAP:
  846.             otmp = mksobj(ROCK, TRUE, FALSE);
  847.             otmp->quan = 1L;
  848.             otmp->owt = weight(otmp);
  849.             if(in_sight) seetrap(trap);
  850.             if(!is_whirly(mptr) && !passes_walls(mptr) &&
  851.                thitm(0, mtmp, otmp, d(2, 6)))
  852.                 trapkilled = TRUE;
  853.             break;
  854.  
  855.         case SQKY_BOARD: {
  856.             register struct monst *ztmp = fmon;
  857.  
  858.             if(is_flyer(mptr)) break;
  859.             /* stepped on a squeaky board */
  860.             if (in_sight) {
  861.                 pline("A board beneath %s squeaks loudly.", mon_nam(mtmp));
  862.                 seetrap(trap);
  863.             } else
  864.                You("hear a distant squeak.");
  865.             /* wake up nearby monsters */
  866.             while(ztmp) {
  867.                 if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
  868.                 if(ztmp->msleep) ztmp->msleep = 0;
  869.                 ztmp = ztmp->nmon;
  870.             }
  871.             break;
  872.         }
  873.  
  874.         case BEAR_TRAP:
  875.             if(mptr->msize > MZ_SMALL &&
  876.                !amorphous(mptr) && !is_flyer(mptr)) {
  877.                 mtmp->mtrapped = 1;
  878.                 if(in_sight) {
  879.                   pline("%s is caught in a bear trap!",
  880.                     Monnam(mtmp));
  881.                   seetrap(trap);
  882.                 } else
  883.                     if((mptr == &mons[PM_OWLBEAR]
  884.                     || mptr == &mons[PM_BUGBEAR])
  885.                     && flags.soundok)
  886.                 You("hear the roaring of an angry bear!");
  887.             }
  888.             break;
  889.  
  890.         case SLP_GAS_TRAP:
  891.             if(!resists_sleep(mptr) &&
  892.                !mtmp->msleep && mtmp->mcanmove) {
  893.                 mtmp->mcanmove = 0;
  894.                 mtmp->mfrozen = rnd(25);
  895.                 if (in_sight) {
  896.                     pline("%s suddenly falls asleep!",
  897.                                 Monnam(mtmp));
  898.                     seetrap(trap);
  899.                 }
  900.             }
  901.             break;
  902.  
  903.         case RUST_TRAP:
  904.             if (in_sight) {
  905.                 pline("A gush of water hits %s!", mon_nam(mtmp));
  906.                 seetrap(trap);
  907.             }
  908.             if (mptr == &mons[PM_IRON_GOLEM]) {
  909.                 if (in_sight)
  910.                     pline("%s falls to pieces!", Monnam(mtmp));
  911.                 else if(mtmp->mtame)
  912.                     pline("May %s rust in peace.",
  913.                                 mon_nam(mtmp));
  914.                 mondied(mtmp);
  915.                 trapkilled = TRUE;
  916.             } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
  917.                 struct monst *mtmp2 = clone_mon(mtmp);
  918.  
  919.                 if (mtmp2) {
  920.                     mtmp2->mhpmax = (mtmp->mhpmax /= 2);
  921.                     if(in_sight)
  922.                     pline("%s multiplies.", Monnam(mtmp));
  923.                 }
  924.             }
  925.             break;
  926.  
  927.         case FIRE_TRAP:
  928.             if (in_sight)
  929.         pline("A tower of flame bursts from the floor under %s!",
  930.                     mon_nam(mtmp));
  931.             if(resists_fire(mptr)) {
  932.                 if (in_sight) {
  933.                 shieldeff(mtmp->mx,mtmp->my);
  934.                 pline("%s is uninjured.", Monnam(mtmp));
  935.                 }
  936.             } else {
  937.                 int num=rnd(6);
  938.  
  939.                 if (thitm(0, mtmp, (struct obj *)0, num))
  940.                 trapkilled = TRUE;
  941.                 else mtmp->mhpmax -= num;
  942.             }
  943.             (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
  944.             (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
  945.             (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
  946.             if (in_sight) seetrap(trap);
  947.             break;
  948.  
  949.         case PIT:
  950.         case SPIKED_PIT:
  951.             if ( !is_flyer(mptr) && 
  952.                  (!mtmp->wormno || (count_wsegs(mtmp) < 6)) &&
  953.                  !is_clinger(mptr) ) {
  954.                 if (!passes_walls(mptr))
  955.                     mtmp->mtrapped = 1;
  956.                 if(in_sight) {
  957.                     pline("%s falls into a pit!", Monnam(mtmp));
  958.                     seetrap(trap);
  959.                 }
  960.                 if(thitm(0, mtmp, (struct obj *)0,
  961.                      rnd((tt==PIT) ? 6 : 10)))
  962.                     trapkilled = TRUE;
  963.             }
  964.             break;
  965.  
  966.         case TRAPDOOR:
  967.             if(!Can_fall_thru(&u.uz))
  968.                 panic("Trapdoors cannot exist on this level.");
  969.  
  970.             if ( (mptr == &mons[PM_WUMPUS]) ||
  971.                  (mtmp->wormno && count_wsegs(mtmp) > 5) ) break;
  972.             tdoor = TRUE;
  973.             /* Fall through */
  974.         case LEVEL_TELEP:
  975.             /* long worms w/tails can now change levels! - Norm */
  976.             if (!is_flyer(mptr)) {
  977.                 register int nlev;
  978.                 d_level tolevel;
  979. #ifdef WALKIES
  980.                 if(teleport_pet(mtmp)) {
  981. #endif
  982.                 if(tdoor) {
  983.                     if(Is_stronghold(&u.uz))
  984.                         assign_level(&tolevel, &valley_level);
  985.                     else if(Is_botlevel(&u.uz)) {
  986.                         pline("%s avoids the trap.", 
  987.                                       Monnam(mtmp));
  988.                     break;
  989.                     } else get_level(&tolevel,depth(&u.uz)+1);
  990.                 } else {
  991. #ifdef MULDGN
  992.                     if(Is_knox(&u.uz)) {
  993.                         rloc(mtmp);
  994.                     break;
  995.                     }
  996. #endif
  997.                     nlev = rnd(3);
  998.                     if(!rn2(2)) nlev = -(nlev);
  999.                     nlev = dunlev(&u.uz) + nlev;
  1000.                     if(nlev > dunlevs_in_dungeon(&u.uz)) {
  1001.                         nlev = dunlevs_in_dungeon(&u.uz);
  1002.                     /* teleport up if already on bottom */
  1003.                     if (Is_botlevel(&u.uz)) 
  1004.                         nlev -= rnd(3);
  1005.                     }
  1006.                     if (nlev < 1) {
  1007.                     nlev = 1;
  1008.                     if (dunlev(&u.uz) == 1) {
  1009.                         nlev += rnd(3);
  1010.                         if (nlev >
  1011.                               dunlevs_in_dungeon(&u.uz)) 
  1012.                             nlev = 
  1013.                           dunlevs_in_dungeon(&u.uz);
  1014.                     }
  1015.                     }
  1016.                     /* can't seem to go anywhere    */
  1017.                     /* (possible in short dungeons) */
  1018.                     if (nlev == dunlev(&u.uz)) {
  1019.                     rloc(mtmp);
  1020.                     break;
  1021.                     }
  1022.                     nlev = dungeons[u.uz.dnum].depth_start +
  1023.                                                nlev;
  1024.                     get_level(&tolevel, nlev);
  1025.                 }
  1026.                 if(in_sight) {
  1027.         pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
  1028.                     seetrap(trap);
  1029.                 }
  1030.                 migrate_to_level(mtmp, 
  1031.                          ledger_no(&tolevel), 0);
  1032.                 return(3);    /* no longer on this level */
  1033. #ifdef WALKIES
  1034.                 }
  1035. #endif
  1036.             }
  1037.             break;
  1038.  
  1039.         case TELEP_TRAP:
  1040.         case MAGIC_PORTAL:
  1041. #ifdef WALKIES
  1042.             if(teleport_pet(mtmp)) {
  1043. #endif
  1044.                 /* Note: don't remove the trap if a vault.  Other-
  1045.                  * wise the monster will be stuck there, since 
  1046.                  * the guard isn't going to come for it...
  1047.                  * Also: don't remove if magic portal.  In short,
  1048.                  * don't remove :-)
  1049.                  */
  1050.                 if (in_sight) {
  1051.                 pline("%s suddenly disappears!", 
  1052.                                       Monnam(mtmp));
  1053.                 seetrap(trap);
  1054.                 }
  1055.                 if (trap->once) vloc(mtmp);
  1056.                 else rloc(mtmp);
  1057. #ifdef WALKIES
  1058.             }
  1059. #endif
  1060.             break;
  1061.  
  1062.            case WEB:
  1063.             /* Monster in a web. */
  1064.             if (mptr->mlet == S_SPIDER) break;
  1065.             if (amorphous(mptr)) {
  1066.                 if (acidic(mptr) ||
  1067.                  mptr == &mons[PM_GELATINOUS_CUBE]) {
  1068.                 if (in_sight)
  1069.                     pline("%s dissolves a spider web.",
  1070.                         Monnam(mtmp));
  1071.                 deltrap(trap);
  1072.                 break;
  1073.                 }
  1074.                 if (in_sight)
  1075.                 pline("%s flows through a spider web.",
  1076.                         Monnam(mtmp));
  1077.                 break;
  1078.             }            
  1079.             switch (monsndx(mptr)) {
  1080.                 case PM_FIRE_ELEMENTAL:
  1081.                 if (in_sight)
  1082.                     pline("%s burns a spider web!", Monnam(mtmp));
  1083.                 deltrap(trap);
  1084.                 break;
  1085.                 case PM_OWLBEAR: /* Eric Backus */
  1086.                 case PM_BUGBEAR:
  1087.                 if (!in_sight) {
  1088.                     You("hear the roaring of a confused bear!");
  1089.                     mtmp->mtrapped = 1;
  1090.                     break;
  1091.                 }
  1092.                 /* fall though */
  1093.                 default:
  1094.                 if (in_sight)
  1095.                     pline("%s is caught in a spider web.",
  1096.                                 Monnam(mtmp));
  1097.                 mtmp->mtrapped = 1;
  1098.                 break;
  1099.             }
  1100.             break;
  1101.  
  1102.         case STATUE_TRAP:
  1103.             break;
  1104.  
  1105.         case MAGIC_TRAP:
  1106.             /* A magic trap.  Monsters immune. */
  1107.             break;
  1108.         case ANTI_MAGIC:    
  1109.                         break;
  1110.  
  1111.         case LANDMINE: {
  1112.             register struct monst *mntmp = fmon;
  1113.  
  1114.             if(rn2(3))
  1115.                 break; /* monsters usually don't set it off */
  1116.             if(is_flyer(mptr)) {
  1117.                 if (in_sight) {
  1118.     pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp));
  1119.                     seetrap(trap);
  1120.                 }
  1121.                 if (rn2(3)) break;
  1122.                 if (in_sight)
  1123.                     pline("The air currents set it off!");
  1124.             } else if(in_sight)
  1125.                 pline("KAABLAMM!!!  %s triggers a land mine!",
  1126.                   Monnam(mtmp));
  1127.             if (!in_sight)
  1128.                 pline("Kaablamm!  You hear an explosion in the distance!");
  1129.             deltrap(trap);
  1130.             if(thitm(0, mtmp, (struct obj *)0, rnd(16)))
  1131.                 trapkilled = TRUE;
  1132.             /* wake everything on the level */
  1133.             while(mntmp) {
  1134.                 if(mntmp->msleep)
  1135.                     mntmp->msleep = 0;
  1136.                 mntmp = mntmp->nmon;
  1137.             }
  1138.             if (unconscious()) {
  1139.                 multi = -1;
  1140.                 nomovemsg="The explosion awakens you!";
  1141.             }
  1142.             break;
  1143.         }
  1144.  
  1145. #ifdef POLYSELF
  1146.         case POLY_TRAP:
  1147.             if(!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
  1148.             (void) newcham(mtmp, (struct permonst *)0);
  1149.             if (in_sight) seetrap(trap);
  1150.             }
  1151.             break;
  1152. #endif
  1153.  
  1154.         default:
  1155.             impossible("Some monster encountered a strange trap of type %d.", tt);
  1156.         }
  1157.     }
  1158.     if(trapkilled) return 2;
  1159.     return mtmp->mtrapped;
  1160. }
  1161.  
  1162. #endif /* OVL1 */
  1163. #ifdef OVLB
  1164.  
  1165. void
  1166. selftouch(arg)
  1167. const char *arg;
  1168. {
  1169.     if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)
  1170. #ifdef POLYSELF
  1171.             && !resists_ston(uasmon)
  1172. #endif
  1173.     ){
  1174.         pline("%s touch the cockatrice corpse.", arg);
  1175. #ifdef POLYSELF
  1176.         if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
  1177.             return;
  1178. #endif
  1179.         You("turn to stone...");
  1180.         killer_format = KILLED_BY;
  1181.         killer = "touching a cockatrice corpse";
  1182.         done(STONING);
  1183.     }
  1184. }
  1185.  
  1186. void
  1187. float_up()
  1188. {
  1189.     if(u.utrap) {
  1190.         if(u.utraptype == TT_PIT) {
  1191.             u.utrap = 0;
  1192.             You("float up, out of the pit!");
  1193.             vision_full_recalc = 1;    /* vision limits change */
  1194.             fill_pit(u.ux, u.uy);
  1195.         } else if (u.utraptype == TT_INFLOOR) {
  1196.             Your("body pulls upward, but your %s are still stuck.",
  1197.                  makeplural(body_part(LEG)));
  1198.         } else {
  1199.             You("float up, only your %s is still stuck.",
  1200.                 body_part(LEG));
  1201.         }
  1202.     }
  1203.     else if(Is_waterlevel(&u.uz))
  1204.         pline("It feels as though you'd lost some weight.");
  1205.     else if(u.uinwater)
  1206.         spoteffects();
  1207.     else if (Hallucination)
  1208.         pline("Up, up, and awaaaay!  You're walking on air!");
  1209.     else if(Is_airlevel(&u.uz))
  1210.         You("gain control over your movements.");
  1211.     else
  1212.         You("start to float in the air!");
  1213. }
  1214.  
  1215. void
  1216. fill_pit(x, y)
  1217. int x, y;
  1218. {
  1219.     struct obj *otmp;
  1220.     struct trap *t;
  1221.  
  1222.     if ((t = t_at(x, y)) && 
  1223.         ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) &&
  1224.         (otmp = sobj_at(BOULDER, x, y))) {
  1225.         freeobj(otmp);
  1226.         (void) flooreffects(otmp, x, y, "settle");
  1227.     }
  1228. }
  1229.  
  1230. int
  1231. float_down()
  1232. {
  1233.     register struct trap *trap = (struct trap *)0;
  1234.     boolean no_msg = FALSE;
  1235.  
  1236.     if(Levitation) return(0); /* maybe another ring/potion/boots */
  1237.  
  1238.     if (Punished && !carried(uball) &&
  1239.         (is_pool(uball->ox, uball->oy) || 
  1240.          ((trap = t_at(uball->ox, uball->oy)) && 
  1241.           ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT) ||
  1242.            (trap->ttyp == TRAPDOOR))))) {
  1243.             u.ux0 = u.ux;
  1244.             u.uy0 = u.uy;
  1245.             u.ux = uball->ox;
  1246.             u.uy = uball->oy;
  1247.             movobj(uchain, uball->ox, uball->oy);
  1248.             newsym(u.ux0, u.uy0);
  1249.             vision_full_recalc = 1;    /* in case the hero moved. */
  1250.     }
  1251.     /* check for falling into pool - added by GAN 10/20/86 */
  1252. #ifdef POLYSELF
  1253.     if(!is_flyer(uasmon)) {
  1254. #endif
  1255.         /* kludge alert:
  1256.          * drown() and lava_effects() print various messages almost
  1257.          * every time they're called which conflict with the "fall
  1258.          * into" message below.  Thus, we want to avoid printing
  1259.          * confusing, duplicate or out-of-order messages.
  1260.          * Use knowledge of the two routines as a hack -- this
  1261.          * should really handled differently -dlc
  1262.          */
  1263.         if(is_pool(u.ux,u.uy) && !Wwalking && !u.uinwater)
  1264.             no_msg = drown();
  1265.  
  1266.         if(is_lava(u.ux,u.uy)) {
  1267.             (void) lava_effects();
  1268.             no_msg = TRUE;
  1269.         }
  1270. #ifdef POLYSELF
  1271.     }
  1272. #endif
  1273.     if (!trap) {
  1274.         if(Is_airlevel(&u.uz))
  1275.             You("begin to tumble in place.");
  1276.         if(Is_waterlevel(&u.uz) && !no_msg)
  1277.             You("feel heavier.");
  1278.         /* u.uinwater msgs already in spoteffects()/drown() */
  1279.         else if (!u.uinwater && !no_msg) {
  1280.             if (Hallucination)
  1281.                 pline("Bummer!  You've %s.",
  1282.                       is_pool(u.ux,u.uy) ?
  1283.                           "splashed down" : "hit the ground");
  1284.             else
  1285.                 You("float gently to the %s.",
  1286.                     is_pool(u.ux,u.uy) ? "water" : "ground");
  1287.         }
  1288.         trap = t_at(u.ux,u.uy);
  1289.     }
  1290.  
  1291.     if(trap)
  1292.         switch(trap->ttyp) {
  1293.         case STATUE_TRAP:
  1294.             break;
  1295.         case TRAPDOOR:
  1296.             if(!Can_fall_thru(&u.uz) || u.ustuck)
  1297.                 break;
  1298.             /* fall into next case */
  1299.         default:
  1300.             dotrap(trap);
  1301.     }
  1302.     if(!flags.nopick && OBJ_AT(u.ux, u.uy) &&
  1303.        !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) &&
  1304.        (!is_pool(u.ux,u.uy) || Underwater))
  1305.         pickup(1);
  1306.     return 0;
  1307. }
  1308.  
  1309.  
  1310. void
  1311. tele()
  1312. {
  1313.     coord cc;
  1314.  
  1315.     /* Disable teleportation in stronghold && Vlad's Tower */
  1316.     if(level.flags.noteleport) {
  1317. #ifdef WIZARD
  1318.         if (!wizard) {
  1319. #endif
  1320.             pline("A mysterious force prevents you from teleporting!");
  1321.             return;
  1322. #ifdef WIZARD
  1323.         }
  1324. #endif
  1325.     }
  1326.  
  1327.     /* don't show trap if "Sorry..." */
  1328.     if(!Blinded) make_blinded(0L,FALSE);
  1329.  
  1330.     if((u.uhave.amulet || Is_wiz1_level(&u.uz) || Is_wiz2_level(&u.uz) ||
  1331.            Is_wiz3_level(&u.uz)) && !rn2(3)) {
  1332.         You("feel disoriented for a moment.");
  1333.         return;
  1334.     }
  1335.     if(Teleport_control
  1336. #ifdef WIZARD
  1337.                 || wizard
  1338. #endif
  1339.                     ) {
  1340.         if (unconscious())
  1341.         pline("Being unconscious, you cannot control your teleport.");
  1342.         else {
  1343.             pline("To what position do you want to be teleported?");
  1344.             cc.x = u.ux;
  1345.             cc.y = u.uy;
  1346.             getpos(&cc, TRUE, "the desired position");/* force valid*/
  1347.                     if(cc.x == -10) return; /* abort */
  1348.             /* possible extensions: introduce a small error if
  1349.                magic power is low; allow transfer to solid rock */
  1350.             if(teleok(cc.x, cc.y, FALSE)){
  1351.             teleds(cc.x, cc.y);
  1352.             return;
  1353.             }
  1354.             pline("Sorry...");
  1355.         }
  1356.     }
  1357.  
  1358.     (void) safe_teleds();
  1359. }
  1360.  
  1361. void
  1362. teleds(nux, nuy)
  1363. register int nux,nuy;
  1364. {
  1365.     if (Punished) unplacebc();
  1366.     u.utrap = 0;
  1367.     u.ustuck = 0;
  1368.     u.ux0 = u.ux;
  1369.     u.uy0 = u.uy;
  1370.     u.ux = nux;
  1371.     u.uy = nuy;
  1372.     fill_pit(u.ux0, u.uy0); /* do this now so that cansee() is correct */
  1373. #ifdef POLYSELF
  1374.     if (hides_under(uasmon))
  1375.         u.uundetected = OBJ_AT(nux, nuy);
  1376.     else 
  1377.         u.uundetected = 0;
  1378.     if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC;
  1379. #endif
  1380.     if(Punished) placebc();
  1381.     if(u.uswallow){
  1382.         u.uswldtim = u.uswallow = 0;
  1383.         docrt();
  1384.     }
  1385.     initrack(); /* teleports mess up tracking monsters without this */
  1386.     /*
  1387.      *  Make sure the hero disappears from the old location.  This will
  1388.      *  not happen if she is teleported within sight of her previous
  1389.      *  location.  Force a full vision recalculation because the hero
  1390.      *  is now in a new location.
  1391.      */
  1392.     newsym(u.ux0,u.uy0);
  1393.     vision_full_recalc = 1;
  1394.     nomul(0);
  1395.     spoteffects();
  1396. }
  1397.  
  1398. int
  1399. dotele()
  1400. {
  1401.     struct trap *trap;
  1402.     boolean castit = FALSE;
  1403.     register int sp_no = 0;
  1404.  
  1405.     trap = t_at(u.ux, u.uy);
  1406.     if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
  1407.         trap = 0;
  1408.  
  1409.     if (trap) {
  1410.         if (trap->once) {
  1411.             pline("This is a vault teleport, usable once only.");
  1412.             if (yn("Jump in?") == 'n')
  1413.                 trap = 0;
  1414.             else {
  1415.                 deltrap(trap);
  1416.                 newsym(u.ux, u.uy);
  1417.             }
  1418.         }
  1419.         if (trap)
  1420. #ifdef POLYSELF
  1421.             You("%s onto the teleportation trap.",
  1422.                 locomotion(uasmon, "jump"));
  1423. #else
  1424.             You("jump onto the teleportation trap.");
  1425. #endif
  1426.     }
  1427.     if(!trap && (!Teleportation ||
  1428.        (u.ulevel < (pl_character[0] == 'W' ? 8 : 12)
  1429. #ifdef POLYSELF
  1430.         && !can_teleport(uasmon)
  1431. #endif
  1432.        )
  1433.       )) {
  1434.         /* Try to use teleport away spell. */
  1435.         castit = objects[SPE_TELEPORT_AWAY].oc_name_known;
  1436.         if (castit) {
  1437.             for (sp_no = 0; sp_no < MAXSPELL &&
  1438.                 spl_book[sp_no].sp_id != NO_SPELL &&
  1439.                 spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++);
  1440.  
  1441.             if (sp_no == MAXSPELL ||
  1442.             spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY)
  1443.                 castit = FALSE;
  1444.         }
  1445. #ifdef WIZARD
  1446.         if (!wizard) {
  1447. #endif
  1448.             if (!castit) {
  1449.             if (!Teleportation)
  1450.                 You("don't know that spell.");
  1451.             else You("are not able to teleport at will.");
  1452.             return(0);
  1453.             }
  1454. #ifdef WIZARD
  1455.         }
  1456. #endif
  1457.     }
  1458.  
  1459.     if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) {
  1460.         You("lack the strength for a teleport spell.");
  1461. #ifdef WIZARD
  1462.         if(!wizard)
  1463. #endif
  1464.         return(1);
  1465.     }
  1466.     if(!trap &&
  1467.       check_capacity("Your concentration falters from carrying so much."))
  1468.         return 1;
  1469.  
  1470.     if (castit) {
  1471.         exercise(A_WIS, TRUE);
  1472.         if (spelleffects(++sp_no, TRUE))
  1473.             return(1);
  1474.         else
  1475. #ifdef WIZARD
  1476.             if (!wizard)
  1477. #endif
  1478.             return(0);
  1479.     }
  1480. #ifdef WALKIES
  1481.     if(next_to_u()) {
  1482. #endif
  1483.         if (trap && trap->once) vtele();
  1484.         else tele();
  1485. #ifdef WALKIES
  1486.         (void) next_to_u();
  1487.     } else {
  1488.         You(shudder_for_moment);
  1489.         return(0);
  1490.     }
  1491. #endif
  1492.     if (!trap) morehungry(100);
  1493.     return(1);
  1494. }
  1495.  
  1496.  
  1497. void
  1498. level_tele()
  1499. {
  1500.     register int newlev;
  1501.     d_level newlevel;
  1502.  
  1503.     if((u.uhave.amulet || In_endgame(&u.uz))
  1504. #ifdef WIZARD
  1505.                         && !wizard
  1506. #endif
  1507.                             ) {
  1508.         You("feel very disoriented for a moment.");
  1509.         return;
  1510.     }
  1511.     if(Teleport_control
  1512. #ifdef WIZARD
  1513.        || wizard
  1514. #endif
  1515.         ) {
  1516.         char buf[BUFSZ];
  1517.  
  1518.         do {
  1519.           getlin("To what level do you want to teleport? [type a number]",
  1520.             buf);
  1521.         } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
  1522.         newlev = atoi(buf);
  1523.  
  1524.         /* no dungeon escape via this route */
  1525.         if(newlev == 0) {
  1526.             if(ynq("Go to Nowhere.  Are you sure?") != 'y') return;
  1527.             You("scream in agony as your body begins to warp...");
  1528.         display_nhwindow(WIN_MESSAGE, FALSE);
  1529.             You("cease to exist.");
  1530.             killer_format = NO_KILLER_PREFIX;
  1531.             killer = "committed suicide";
  1532.             done(DIED);
  1533.         return;  
  1534.         }
  1535. #ifdef MULDGN
  1536.         /* if in Knox and the requested level > 0, stay put.
  1537.          * we let negative values requests fall into the "heaven" loop.
  1538.          */
  1539.         if(Is_knox(&u.uz) && newlev > 0) {
  1540.             You(shudder_for_moment);
  1541.         return;
  1542.         }
  1543.         /* if in Quest, the player sees "Home 1", etc., on the status
  1544.          * line, instead of the logical depth of the level.  controlled
  1545.          * level teleport request is likely to be relativized to the
  1546.          * status line, and consequently it should be incremented to 
  1547.          * the value of the logical depth of the target level.
  1548.          *
  1549.          * we let negative values requests fall into the "heaven" loop.
  1550.          */
  1551.         if(In_quest(&u.uz) && newlev > 0)
  1552.             newlev = newlev + dungeons[u.uz.dnum].depth_start - 1;
  1553. #endif
  1554.     } else { /* involuntary level tele */
  1555. #ifdef MULDGN
  1556.         if(Is_knox(&u.uz)) {
  1557.             You(shudder_for_moment);
  1558.         return;
  1559.         }
  1560. #endif
  1561.         if(rn2(5)) newlev = rnd((int)depth(&u.uz) + 3);
  1562.         else {
  1563.         You(shudder_for_moment);
  1564.         return; 
  1565.         }
  1566.         if(newlev == depth(&u.uz)) {
  1567.         /* if in a single-level dungeon... */
  1568.         if(dunlevs_in_dungeon(&u.uz) == 1) {
  1569.             You(shudder_for_moment);
  1570.             return; 
  1571.         }
  1572.         else if(dunlev(&u.uz) == 1) newlev++;
  1573.         else if(dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz)) newlev--;
  1574.             else if(In_hell(&u.uz)) newlev--;
  1575.         else newlev++;
  1576.         } 
  1577.     }
  1578.  
  1579. #ifdef WALKIES
  1580.     if(!next_to_u()) {
  1581.         You(shudder_for_moment);
  1582.         return;
  1583.     }
  1584. #endif
  1585.     if(newlev < 0) {
  1586.         if(newlev <= -10) {
  1587.             You("arrive in heaven.");
  1588.             verbalize("Thou art early, but we'll admit thee.");
  1589.             killer_format = NO_KILLER_PREFIX;
  1590.             killer = "went to heaven prematurely";
  1591.             done(DIED);
  1592.             return;
  1593.         } else    if (newlev == -9) {
  1594.             You("feel deliriously happy. ");
  1595.             pline("(In fact, you're on Cloud 9!) ");
  1596.             display_nhwindow(WIN_MESSAGE, FALSE);
  1597.         } else
  1598.             You("are now high above the clouds...");
  1599.  
  1600.         if(Levitation || is_floater(uasmon)) {
  1601.             You("float gently down to earth.");
  1602.             u.uz.dnum = 0; /* he might have been in another dgn */
  1603.             newlev = 1;
  1604.         }
  1605. #ifdef POLYSELF
  1606.         else if(is_flyer(uasmon)) {
  1607.             You("fly down to earth.");
  1608.             u.uz.dnum = 0; /* he might have been in another dgn */
  1609.             newlev = 1;
  1610.         }
  1611. #endif
  1612.         else {
  1613.             d_level save_dlevel;
  1614.             
  1615.             assign_level(&save_dlevel, &u.uz);
  1616.             pline("Unfortunately, you don't know how to fly.");
  1617.             You("plummet a few thousand feet to your death.");
  1618.             u.uz.dnum = 0;
  1619.             u.uz.dlevel = 0;
  1620.             killer_format = NO_KILLER_PREFIX;
  1621.             killer =
  1622.     self_pronoun("teleported out of the dungeon and fell to %s death","his");
  1623.             done(DIED);
  1624.             assign_level(&u.uz, &save_dlevel);
  1625.             flags.botl = 1;
  1626.             return;
  1627.         }
  1628.     }
  1629.  
  1630. # ifdef WIZARD
  1631.     if (In_endgame(&u.uz)) {    /* must already be wizard */
  1632.         newlevel.dnum = u.uz.dnum;
  1633.         newlevel.dlevel = newlev;
  1634.         goto_level(&newlevel, FALSE, FALSE, FALSE);
  1635.         return;
  1636.     }
  1637. # endif
  1638.  
  1639.     /* calls done(ESCAPED) if newlevel==0 */
  1640.     if(u.uz.dnum == medusa_level.dnum &&
  1641.         newlev >= dungeons[u.uz.dnum].depth_start +
  1642.                         dunlevs_in_dungeon(&u.uz)) {
  1643.  
  1644.         goto_hell(TRUE, FALSE);
  1645.     } else {
  1646.         /* if invocation did not yet occur, teleporting into
  1647.          * the last level of Gehennom is forbidden.
  1648.          */
  1649.         if(Inhell && !u.uevent.invoked &&
  1650.             newlev >= (dungeons[u.uz.dnum].depth_start +
  1651.                     dunlevs_in_dungeon(&u.uz) - 1)) {
  1652.         newlev = dungeons[u.uz.dnum].depth_start +
  1653.                     dunlevs_in_dungeon(&u.uz) - 2;
  1654.         pline("Sorry...");
  1655.         }
  1656. #ifdef MULDGN
  1657.         /* no teleporting out of quest dungeon */
  1658.         if(In_quest(&u.uz) && newlev < depth(&qstart_level))
  1659.         newlev = depth(&qstart_level);
  1660. #endif
  1661.         /* the player thinks of levels purely in logical terms, so
  1662.          * we must translate newlev to a number relative to the
  1663.          * current dungeon.
  1664.            */
  1665.         get_level(&newlevel, newlev);
  1666.         goto_level(&newlevel, FALSE, FALSE, FALSE);
  1667.     }
  1668. }
  1669.  
  1670. static void
  1671. dofiretrap()
  1672. {
  1673.  
  1674.     register int num;
  1675.  
  1676.     /* changed to be in conformance with
  1677.      * SCR_FIRE by GAN 11/02/86
  1678.      */
  1679.  
  1680.     pline("A tower of flame bursts from the floor!");
  1681.     if(Fire_resistance) {
  1682.         shieldeff(u.ux, u.uy);
  1683.         You("are uninjured.");
  1684.     } else {
  1685.         num = rnd(6);
  1686.         u.uhpmax -= num;
  1687.         losehp(num,"burst of flame", KILLED_BY_AN);
  1688.     }
  1689.     destroy_item(SCROLL_CLASS, AD_FIRE);
  1690.     destroy_item(SPBOOK_CLASS, AD_FIRE);
  1691.     destroy_item(POTION_CLASS, AD_FIRE);
  1692. }
  1693.  
  1694. static void
  1695. domagicportal(ttmp)
  1696. register struct trap *ttmp;
  1697. {
  1698.     struct d_level target_level;
  1699.  
  1700.     /* if landed from another portal, do nothing */
  1701.     /* problem: level teleport landing escapes the check */
  1702.     if(!on_level(&u.uz, &u.uz0)) return;
  1703.  
  1704.     You("activated a magic portal!");
  1705.     You("feel dizzy for a moment, but the sensation passes.");
  1706.  
  1707.     /* prevent the poor shnook, whose amulet was stolen  */
  1708.     /* while in the endgame, from accidently triggering  */
  1709.     /* the portal to the next level, and thus losing the */
  1710.     /* game                                              */
  1711.     if(In_endgame(&u.uz) && !u.uhave.amulet) return;
  1712.  
  1713.     target_level = ttmp->dst;
  1714.     goto_level(&target_level, FALSE, FALSE, TRUE);
  1715. }
  1716.  
  1717. static void
  1718. domagictrap()
  1719. {
  1720.     register int fate = rnd(20);
  1721.  
  1722.     /* What happened to the poor sucker? */
  1723.  
  1724.     if (fate < 10) {
  1725.  
  1726.       /* Most of the time, it creates some monsters. */
  1727.       register int cnt = rnd(4);
  1728.  
  1729.       /* below checks for blindness added by GAN 10/30/86 */
  1730.       if (!Blind)  {
  1731.         You("are momentarily blinded by a flash of light!");
  1732.         make_blinded((long)rn1(5,10),FALSE);
  1733.       }  else
  1734.         You("hear a deafening roar!");
  1735.       while(cnt--)
  1736.         (void) makemon((struct permonst *) 0, u.ux, u.uy);
  1737.     }
  1738.     else
  1739.       switch (fate) {
  1740.  
  1741.          case 10:
  1742.          case 11:
  1743.               /* sometimes nothing happens */
  1744.             break;
  1745.          case 12: /* a flash of fire */
  1746.                 dofiretrap();
  1747.             break;
  1748.  
  1749.          /* odd feelings */
  1750.          case 13:    pline("A shiver runs up and down your %s!",
  1751.                   body_part(SPINE));
  1752.             break;
  1753.          case 14:    You(Hallucination ?
  1754.                 "hear the moon howling at you." :
  1755.                 "hear distant howling.");
  1756.             break;
  1757.          case 15:    You("suddenly yearn for %s.",
  1758.                 Hallucination ? "Cleveland" :
  1759.                         "your distant homeland");
  1760.             break;
  1761.          case 16:   Your("pack shakes violently!");
  1762.             break;
  1763.          case 17:    You(Hallucination ?
  1764.                 "smell hamburgers." :
  1765.                 "smell charred flesh.");
  1766.             break;
  1767.  
  1768.          /* very occasionally something nice happens. */
  1769.  
  1770.          case 19:
  1771.             /* tame nearby monsters */
  1772.            {   register int i,j;
  1773.                register struct monst *mtmp;
  1774.  
  1775.                /* below pline added by GAN 10/30/86 */
  1776.                (void) adjattrib(A_CHA,1,FALSE);
  1777.                for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) {
  1778.                if(!isok(u.ux+i, u.uy+j)) continue;
  1779.                mtmp = m_at(u.ux+i, u.uy+j);
  1780.                if(mtmp)
  1781.                    (void) tamedog(mtmp, (struct obj *)0);
  1782.                }
  1783.                break;
  1784.            }
  1785.  
  1786.          case 20:
  1787.             /* uncurse stuff */
  1788.            {  register struct obj *obj;
  1789.  
  1790.             /* below plines added by GAN 10/30/86 */
  1791.             You(Hallucination ?
  1792.                 "feel in touch with the Universal Oneness." :
  1793.                 "feel like someone is helping you.");
  1794.             for(obj = invent; obj ; obj = obj->nobj)
  1795.                    if(obj->owornmask || obj->otyp == LOADSTONE)
  1796.                     uncurse(obj);
  1797.                if(Punished) unpunish();
  1798.                break;
  1799.            }
  1800.          default: break;
  1801.       }
  1802. }
  1803.  
  1804. void
  1805. water_damage(obj,force)
  1806. register struct obj *obj;
  1807. register boolean force;
  1808. {
  1809.     /* Scrolls, spellbooks, potions, weapons and
  1810.        pieces of armor may get affected by the water */
  1811.     for(; obj; obj = obj->nobj) {
  1812.  
  1813.         (void) snuff_lit(obj);
  1814.  
  1815.         if(obj->greased) {
  1816.             if (force || !rn2(2)) obj->greased = 0;
  1817.         } else if(Is_container(obj) && !Is_box(obj) &&
  1818.             (obj->otyp != OILSKIN_SACK || (obj->cursed && !rn2(3)))) {
  1819.             water_damage(obj->cobj,force);
  1820.         } else if(obj->oclass == SCROLL_CLASS && (force || rn2(12) > Luck)
  1821. #ifdef MAIL
  1822.               && obj->otyp != SCR_MAIL
  1823. #endif
  1824.               ) {
  1825.             obj->otyp = SCR_BLANK_PAPER;
  1826.         } else if(obj->oclass == SPBOOK_CLASS && (force || rn2(12) > Luck)) {
  1827.             if (obj->otyp == SPE_BOOK_OF_THE_DEAD)
  1828.                 pline("Steam rises from %s.", the(xname(obj)));
  1829.             else obj->otyp = SPE_BLANK_PAPER;
  1830.         } else if(obj->oclass == POTION_CLASS && (force || rn2(12) > Luck)) {
  1831.             if (obj->spe == -1) {
  1832.                 obj->otyp = POT_WATER;
  1833.                 obj->blessed = obj->cursed = 0;
  1834.                 obj->spe = 0;
  1835.             } else obj->spe--;
  1836.         } else if(is_rustprone(obj) && obj->oeroded < MAX_ERODE &&
  1837.               !(obj->oerodeproof || (obj->blessed && !rnl(4))) &&
  1838.               (force || rn2(12) > Luck)) {
  1839.             /* all metal stuff and armor except body armor
  1840.                protected by oilskin cloak */
  1841.             if(obj->oclass != ARMOR_CLASS || obj != uarm ||
  1842.                !uarmc || uarmc->otyp != OILSKIN_CLOAK ||
  1843.                 (uarmc->cursed && !rn2(3)))
  1844.                 obj->oeroded++;
  1845.         }
  1846.     }
  1847. }
  1848.  
  1849. /*
  1850.  * This function is potentially expensive - rolling
  1851.  * inventory list multiple times.  Luckily it's seldom needed.
  1852.  * Returns TRUE if disrobing made player unencumbered enough to
  1853.  * crawl out of the current predicament.
  1854.  */
  1855. static boolean
  1856. emergency_disrobe(lostsome)
  1857. boolean *lostsome;
  1858. {
  1859.     int invc = inv_cnt();
  1860.  
  1861.     while (near_capacity() > (Punished ? UNENCUMBERED : SLT_ENCUMBER)) {
  1862.         register struct obj *obj, *otmp = (struct obj *)0;
  1863.         register int i = rn2(invc);
  1864.  
  1865.         for (obj = invent; obj; obj = obj->nobj) {
  1866.             /*
  1867.              * Undroppables are: body armor, boots, gloves,
  1868.              * amulets, and rings because of the time and effort
  1869.              * in removing them + loadstone and other cursed stuff
  1870.              * for obvious reasons.
  1871.              */
  1872.             if (!(obj->otyp == LOADSTONE ||
  1873.                   obj == uamul || obj == uleft || obj == uright ||
  1874.                   obj == ublindf || obj == uarm || obj == uarmc ||
  1875.                   obj == uarmg || obj == uarmf ||
  1876. #ifdef TOURIST
  1877.                   obj == uarmu ||
  1878. #endif
  1879.                   (obj->cursed && (obj == uarmh || obj == uarms)) ||
  1880.                   welded(obj)))
  1881.                 otmp = obj;
  1882.             /* reached the mark and found some stuff to drop? */
  1883.             if (--i < 0 && otmp) break;
  1884.  
  1885.             /* else continue */
  1886.         }
  1887.  
  1888.         /* nothing to drop and still overweight */
  1889.         if (!otmp) return(FALSE);
  1890.  
  1891.         if (otmp == uarmh) (void) Helmet_off();
  1892.         else if (otmp == uarms) (void) Shield_off();
  1893.         else if (otmp == uwep) setuwep((struct obj *)0);
  1894.         *lostsome = TRUE;
  1895.         dropx(otmp);
  1896.         invc--;
  1897.     }
  1898.     return(TRUE);
  1899. }
  1900.  
  1901. /*
  1902.  *  return(TRUE) == player relocated
  1903.  */
  1904. boolean
  1905. drown()
  1906. {
  1907.     boolean inpool_ok = FALSE, crawl_ok;
  1908.     int i, x, y;
  1909.  
  1910.     /* happily wading in the same contiguous pool */
  1911.     if (u.uinwater && is_pool(u.ux-u.dx,u.uy-u.dy) &&
  1912.        Magical_breathing) {
  1913.         /* water effects on objects every now and then */
  1914.         if (!rn2(5)) inpool_ok = TRUE;
  1915.         else return(FALSE);
  1916.     }
  1917.  
  1918.     if (!u.uinwater) {
  1919.         You("%s into the water!",
  1920.         Is_waterlevel(&u.uz) ? "plunge" : "fall");
  1921. #ifdef POLYSELF
  1922.         if(!is_swimmer(uasmon))
  1923. #endif
  1924.         if (!Is_waterlevel(&u.uz))
  1925.             You("sink like %s.",
  1926.             Hallucination ? "the Titanic" : "a rock");
  1927.     }
  1928.  
  1929.     water_damage(invent,FALSE);
  1930.  
  1931. #ifdef POLYSELF
  1932.     if(u.umonnum == PM_GREMLIN && rn2(3)) {
  1933.         struct monst *mtmp;
  1934.         if(mtmp = cloneu()) {
  1935.             mtmp->mhpmax = (u.mhmax /= 2);
  1936.             You("multiply.");
  1937.         }
  1938.     }
  1939.  
  1940.     if(is_swimmer(uasmon)) return(FALSE);
  1941. #endif
  1942.     if (inpool_ok) return(FALSE);
  1943. #ifdef WALKIES
  1944.     if ((i = number_leashed()) > 0) {
  1945.         pline("The leash%s slip%s loose.",
  1946.             (i > 1) ? "es" : "",
  1947.             (i > 1) ? "" : "s");
  1948.         unleash_all();
  1949.     }
  1950. #endif
  1951.     if (Magical_breathing) {
  1952.         pline("But wait!");
  1953.         Your("lungs start acting like gills.");
  1954.         if (!Is_waterlevel(&u.uz))
  1955.             Your("%s the bottom.",Hallucination ? "keel hits" : "feet touch");
  1956.         if (Punished) placebc();
  1957.         u.uinwater = 1;
  1958.         under_water(1);
  1959.         return(FALSE);
  1960.     }
  1961.     if((Teleportation || can_teleport(uasmon)) &&
  1962.        (Teleport_control || rn2(3) < Luck+2)) {
  1963.         You("attempt a teleport spell.");    /* utcsri!carroll */
  1964.         (void) dotele();
  1965.         if(!is_pool(u.ux,u.uy))
  1966.             return(TRUE);
  1967.     }
  1968.     crawl_ok = FALSE;
  1969.     /* look around for a place to crawl to */
  1970.     for (i = 0; i < 100; i++) {
  1971.         x = rn1(3,u.ux - 1);
  1972.         y = rn1(3,u.uy - 1);
  1973.         if (teleok(x,y,TRUE)) {
  1974.             crawl_ok = TRUE;
  1975.             goto crawl;
  1976.         }
  1977.     }
  1978.     /* one more scan */
  1979.     for (x = u.ux - 1; x <= u.ux + 1; x++)
  1980.         for (y = u.uy - 1; y <= u.uy + 1; y++)
  1981.             if (teleok(x,y,TRUE)) {
  1982.                 crawl_ok = TRUE;
  1983.                 goto crawl;
  1984.             }
  1985. crawl:;
  1986.     if (crawl_ok) {
  1987.         boolean lost = FALSE;
  1988.         /* time to do some strip-tease... */
  1989.         boolean succ = Is_waterlevel(&u.uz) ? TRUE :
  1990.                 emergency_disrobe(&lost);
  1991.  
  1992.         You("try to crawl out of the water.");
  1993.         if (lost)
  1994.             You("dump some of your gear to lose weight...");
  1995.         if (succ) {
  1996.             pline("Pheew!  That was close.");
  1997.             teleds(x,y);
  1998.             return(TRUE);
  1999.         }
  2000.         /* still too much weight */
  2001.         pline("But in vain.");
  2002.     }
  2003.     u.uinwater = 1;
  2004.     You("drown.");
  2005.     killer_format = KILLED_BY_AN;
  2006.     killer = (levl[u.ux][u.uy].typ == POOL || Is_medusa_level(&u.uz)) ?
  2007.         "pool of water" : "moat";
  2008.     done(DROWNING);
  2009.     /* oops, we're still alive.  better get out of the water. */
  2010.     if (!safe_teleds())
  2011.         while (1) {
  2012.             pline("You're still drowning.");
  2013.             done(DROWNING);
  2014.         }
  2015.     u.uinwater = 0;
  2016.     You("find yourself back %s.",Is_waterlevel(&u.uz) ?
  2017.         "in an air bubble" : "on dry land");
  2018.     return(TRUE);
  2019. }
  2020.  
  2021. void
  2022. drain_en(n)
  2023. register int n;
  2024. {
  2025.     if (!u.uenmax) return;
  2026.     You("feel your magical energy drain away!");
  2027.     u.uen -= n;
  2028.     if(u.uen < 0)  {
  2029.         u.uenmax += u.uen;
  2030.         if(u.uenmax < 0) u.uenmax = 0;
  2031.         u.uen = 0;
  2032.     }
  2033.     flags.botl = 1;
  2034. }
  2035.  
  2036. int
  2037. dountrap()    /* disarm a trapped object */
  2038. {
  2039. #ifdef POLYSELF
  2040.     if(nohands(uasmon)) {
  2041.         pline("And just how do you expect to do that?");
  2042.         return(0);
  2043.     }
  2044. #endif
  2045.     return untrap(FALSE);
  2046. }
  2047.  
  2048. int
  2049. untrap(force)
  2050. boolean force;
  2051. {
  2052.     register struct obj *otmp;
  2053.     register boolean confused = (Confusion > 0 || Hallucination > 0);
  2054.     register int x,y;
  2055.     int ch;
  2056.     struct trap *ttmp;
  2057.     struct monst *mtmp;
  2058.     boolean trap_skipped = FALSE;
  2059.  
  2060.     if(!getdir(NULL)) return(0);
  2061.     x = u.ux + u.dx;
  2062.     y = u.uy + u.dy;
  2063.  
  2064.     if(!u.dx && !u.dy) {
  2065.         for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  2066.         if(Is_box(otmp)) {
  2067.             pline("There is %s here.", doname(otmp));
  2068.  
  2069.             switch (ynq("Check for traps?")) {
  2070.             case 'q': return(0);
  2071.             case 'n': continue;
  2072.             }
  2073.  
  2074.             if((otmp->otrapped && (force || (!confused
  2075.                 && rn2(MAXULEV + 1 - (int)u.ulevel) < 10)))
  2076.                || (!force && confused && !rn2(3))) {
  2077.             You("find a trap on %s!", the(xname(otmp)));
  2078.             exercise(A_WIS, TRUE);
  2079.  
  2080.             switch (ynq("Disarm it?")) {
  2081.                 case 'q': return(1);
  2082.                 case 'n': trap_skipped = TRUE;  continue;
  2083.             }
  2084.  
  2085.             if(otmp->otrapped) {
  2086.                 exercise(A_DEX, TRUE);
  2087.                 ch = ACURR(A_DEX) + u.ulevel;
  2088.                 if (pl_character[0] == 'R') ch *= 2;
  2089.                 if(!force && (confused || Fumbling ||
  2090.                 rnd(75+level_difficulty()/2) > ch)) {
  2091.                 (void) chest_trap(otmp, FINGER, TRUE);
  2092.                 } else {
  2093.                 You("disarm it!");
  2094.                 otmp->otrapped = 0;
  2095.                 }
  2096.             } else pline("That %s was not trapped.", doname(otmp));
  2097.             return(1);
  2098.             } else {
  2099.             You("find no traps on %s.", the(xname(otmp)));
  2100.             return(1);
  2101.             }
  2102.         }
  2103.         if ((ttmp = t_at(x,y)) && ttmp->tseen)
  2104.         You("cannot disable this trap.");
  2105.         else
  2106.         You(trap_skipped ? "find no other traps here."
  2107.                  : "know of no traps here.");
  2108.         return(0);
  2109.     }
  2110.  
  2111.     if ((mtmp = m_at(x,y))                &&
  2112.         mtmp->m_ap_type == M_AP_FURNITURE    &&
  2113.         (mtmp->mappearance == S_hcdoor ||
  2114.             mtmp->mappearance == S_vcdoor)    &&
  2115.         !Protection_from_shape_changers)     {
  2116.  
  2117.         stumble_onto_mimic(mtmp);
  2118.         return(1);
  2119.     }
  2120.  
  2121.     if (!IS_DOOR(levl[x][y].typ)) {
  2122.         if ((ttmp = t_at(x,y)) && ttmp->tseen)
  2123.         You("cannot disable that trap.");
  2124.         else
  2125.         You("know of no traps there.");
  2126.         return(0);
  2127.     }
  2128.  
  2129.     switch (levl[x][y].doormask) {
  2130.         case D_NODOOR:
  2131.         You("%s no door there.", Blind ? "feel" : "see");
  2132.         return(0);
  2133.         case D_ISOPEN:
  2134.         pline("This door is safely open.");
  2135.         return(0);
  2136.         case D_BROKEN:
  2137.         pline("This door is broken.");
  2138.         return(0);
  2139.     }
  2140.  
  2141.     if ((levl[x][y].doormask & D_TRAPPED
  2142.          && (force ||
  2143.          (!confused && rn2(MAXULEV - (int)u.ulevel + 11) < 10)))
  2144.         || (!force && confused && !rn2(3))) {
  2145.         You("find a trap on the door!");
  2146.         exercise(A_WIS, TRUE);
  2147.         if (ynq("Disarm it?") != 'y') return(1);
  2148.         if (levl[x][y].doormask & D_TRAPPED) {
  2149.             ch = 15 +
  2150.              (pl_character[0] == 'R') ? u.ulevel*3 :
  2151.              u.ulevel;
  2152.             exercise(A_DEX, TRUE);
  2153.             if(!force && (confused || Fumbling || 
  2154.                              rnd(75+level_difficulty()/2) > ch)) {
  2155.                 You("set it off!");
  2156.                 b_trapped("door");
  2157.             } else
  2158.                 You("disarm it!");
  2159.             levl[x][y].doormask &= ~D_TRAPPED;
  2160.         } else pline("This door was not trapped.");
  2161.         return(1);
  2162.     } else {
  2163.         You("find no traps on the door.");
  2164.         return(1);
  2165.     }
  2166. }
  2167.  
  2168. /* only called when the player is doing something to the chest directly */
  2169. boolean
  2170. chest_trap(obj, bodypart, disarm)
  2171. register struct obj *obj;
  2172. register int bodypart;
  2173. boolean disarm;
  2174. {
  2175.     register struct obj *otmp = obj, *otmp2;
  2176.     char    buf[80];
  2177.     const char *msg;
  2178.  
  2179.     You(disarm ? "set it off!" : "trigger a trap!");
  2180.     display_nhwindow(WIN_MESSAGE, FALSE);
  2181.     if (Luck > -13 && rn2(13+Luck) > 7) {    /* saved by luck */
  2182.         /* trap went off, but good luck prevents damage */
  2183.         switch (rn2(13)) {
  2184.         case 12:
  2185.         case 11:  msg = "explosive charge is a dud";  break;
  2186.         case 10:
  2187.         case  9:  msg = "electric charge is grounded";  break;
  2188.         case  8:
  2189.         case  7:  msg = "flame fizzles out";  break;
  2190.         case  6:
  2191.         case  5:
  2192.         case  4:  msg = "poisoned needle misses";  break;
  2193.         case  3:
  2194.         case  2:
  2195.         case  1:
  2196.         case  0:  msg = "gas cloud blows away";  break;
  2197.         default:  impossible("chest disarm bug");  msg = NULL;  break;
  2198.         }
  2199.         if (msg) pline("But luckily the %s!", msg);
  2200.     } else {
  2201.         switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) {
  2202.         case 25:
  2203.         case 24:
  2204.         case 23:
  2205.         case 22:
  2206.         case 21: {
  2207.                   register struct monst *shkp;
  2208.               long loss = 0L;
  2209.               boolean costly, insider;
  2210.               register xchar ox = obj->ox, oy = obj->oy;
  2211.  
  2212. #ifdef GCC_WARN
  2213.               shkp = (struct monst *) 0;
  2214. #endif
  2215.               /* the obj location need not be that of player */
  2216.               costly = (costly_spot(ox, oy) && 
  2217.                    (shkp = shop_keeper(*in_rooms(ox, oy,
  2218.                     SHOPBASE))) != (struct monst *)0);
  2219.               insider = (*u.ushops && inside_shop(u.ux, u.uy) &&
  2220.                     *in_rooms(ox, oy, SHOPBASE) == *u.ushops);
  2221.  
  2222.               pline("%s explodes!", The(xname(obj)));
  2223.               Sprintf(buf, "exploding %s", xname(obj));
  2224.  
  2225.               if(costly)
  2226.                   loss += stolen_value(obj, ox, oy,
  2227.                         (boolean)shkp->mpeaceful, TRUE);
  2228.               delete_contents(obj);
  2229.               for(otmp = level.objects[u.ux][u.uy];
  2230.                             otmp; otmp = otmp2) {
  2231.                   otmp2 = otmp->nexthere;
  2232.                   if(costly)
  2233.                       loss += stolen_value(otmp, otmp->ox, 
  2234.                       otmp->oy, (boolean)shkp->mpeaceful,
  2235.                       TRUE);
  2236.                   delobj(otmp);
  2237.               }
  2238.               exercise(A_STR, FALSE);
  2239.               losehp(d(6,6), buf, KILLED_BY_AN);
  2240.               if(costly && loss) {
  2241.                   if(insider)
  2242.                   You("owe %ld zorkmids for objects destroyed.",
  2243.                                               loss);
  2244.                   else {
  2245.                             You("caused %ld zorkmids worth of damage!",
  2246.                                                   loss);
  2247.                       make_angry_shk(shkp, ox, oy);
  2248.                   }
  2249.               }
  2250.               wake_nearby();
  2251.               return TRUE;
  2252.             }
  2253.         case 20:
  2254.         case 19:
  2255.         case 18:
  2256.         case 17:
  2257.             pline("A cloud of noxious gas billows from %s.",
  2258.                   the(xname(obj)));
  2259.             poisoned("gas cloud", A_STR, "cloud of poison gas",15);
  2260.             exercise(A_CON, FALSE);
  2261.             break;
  2262.         case 16:
  2263.         case 15:
  2264.         case 14:
  2265.         case 13:
  2266.             You("feel a needle prick your %s.",body_part(bodypart));
  2267.             poisoned("needle", A_CON, "poison needle",10);
  2268.             exercise(A_CON, FALSE);
  2269.             break;
  2270.         case 12:
  2271.         case 11:
  2272.         case 10:
  2273.         case 9:
  2274.             pline("A tower of flame erupts from %s!",
  2275.                   the(xname(obj)));
  2276.             if(Fire_resistance) {
  2277.                 shieldeff(u.ux, u.uy);
  2278.                 You("don't seem to be affected.");
  2279.             } else    losehp(d(4, 6), "tower of flame", KILLED_BY_AN);
  2280.             destroy_item(SCROLL_CLASS, AD_FIRE);
  2281.             destroy_item(SPBOOK_CLASS, AD_FIRE);
  2282.             destroy_item(POTION_CLASS, AD_FIRE);
  2283.             break;
  2284.         case 8:
  2285.         case 7:
  2286.         case 6:
  2287.             You("are jolted by a surge of electricity!");
  2288.             if(Shock_resistance)  {
  2289.                 shieldeff(u.ux, u.uy);
  2290.                 You("don't seem to be affected.");
  2291.             } else    losehp(d(4, 4), "electric shock", KILLED_BY_AN);
  2292.             destroy_item(RING_CLASS, AD_ELEC);
  2293.             destroy_item(WAND_CLASS, AD_ELEC);
  2294.             break;
  2295.         case 5:
  2296.         case 4:
  2297.         case 3:
  2298.             pline("Suddenly you are frozen in place!");
  2299.             nomul(-d(5, 6));
  2300.             exercise(A_DEX, FALSE);
  2301.             nomovemsg = "You can move again.";
  2302.             break;
  2303.         case 2:
  2304.         case 1:
  2305.         case 0:
  2306.             pline("A cloud of %s gas billows from %s",
  2307.                   hcolor(), the(xname(obj)));
  2308.             if(!Stunned)
  2309.                 if (Hallucination)
  2310.                 pline("What a groovy feeling!");
  2311.                 else
  2312.                 You("stagger and your vision blurs...");
  2313.             make_stunned(HStun + rn1(7, 16),FALSE);
  2314.             make_hallucinated(HHallucination + rn1(5, 16),FALSE,0L);
  2315.             break;
  2316.         default: impossible("bad chest trap");
  2317.             break;
  2318.         }
  2319.         bot();            /* to get immediate botl re-display */
  2320.     }
  2321.     otmp->otrapped = 0;        /* these traps are one-shot things */
  2322.  
  2323.     return FALSE;
  2324. }
  2325.  
  2326. #endif /* OVLB */
  2327. #ifdef OVL0
  2328.  
  2329. struct trap *
  2330. t_at(x,y)
  2331. register int x, y;
  2332. {
  2333.     register struct trap *trap = ftrap;
  2334.     while(trap) {
  2335.         if(trap->tx == x && trap->ty == y) return(trap);
  2336.         trap = trap->ntrap;
  2337.     }
  2338.     return((struct trap *)0);
  2339. }
  2340.  
  2341. #endif /* OVL0 */
  2342. #ifdef OVLB
  2343.  
  2344. void
  2345. deltrap(trap)
  2346. register struct trap *trap;
  2347. {
  2348.     register struct trap *ttmp;
  2349.  
  2350.     if(trap == ftrap)
  2351.         ftrap = ftrap->ntrap;
  2352.     else {
  2353.         for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
  2354.         ttmp->ntrap = trap->ntrap;
  2355.     }
  2356.     dealloc_trap(trap);
  2357. }
  2358.  
  2359. /* used for doors.  can be used for anything else that opens. */
  2360. void
  2361. b_trapped(item)
  2362. register const char *item;
  2363. {
  2364.     register int lvl = level_difficulty();
  2365.     int dmg = rnd(5 + (lvl<5 ? lvl : 2+lvl/2));
  2366.  
  2367.     pline("KABOOM!!  %s was booby-trapped!", The(item));
  2368.     if (u.ulevel < 4 && lvl < 3 && !rnl(3))
  2369.         You("are shaken, but luckily unhurt.");        
  2370.     else losehp(dmg, "explosion", KILLED_BY_AN);
  2371.     exercise(A_STR, FALSE);
  2372.     make_stunned(HStun + dmg, TRUE);
  2373. }
  2374.  
  2375. /* Monster is hit by trap. */
  2376. /* Note: doesn't work if both obj and d_override are null */
  2377. STATIC_OVL boolean
  2378. thitm(tlev, mon, obj, d_override)
  2379. register int tlev;
  2380. register struct monst *mon;
  2381. register struct obj *obj;
  2382. int d_override;
  2383. {
  2384.     register int strike;
  2385.     register boolean trapkilled = FALSE;
  2386.  
  2387.     if (d_override) strike = 1;
  2388.     else if (obj) strike = (find_mac(mon) + tlev + obj->spe <= rnd(20));
  2389.     else strike = (find_mac(mon) + tlev <= rnd(20));
  2390.  
  2391.     /* Actually more accurate than thitu, which doesn't take
  2392.      * obj->spe into account.
  2393.      */
  2394.     if(!strike) {
  2395.         if (cansee(mon->mx, mon->my))
  2396.             pline("%s is almost hit by %s!", Monnam(mon),
  2397.                                 doname(obj));
  2398.     } else {
  2399.         int dam = 1;
  2400.  
  2401.         if (obj && cansee(mon->mx, mon->my))
  2402.             pline("%s is hit by %s!", Monnam(mon), doname(obj));
  2403.         if (d_override) dam = d_override;
  2404.         else if (obj) {
  2405.             dam = dmgval(obj, mon->data);
  2406.             if (dam < 1) dam = 1;
  2407.         }
  2408.         if ((mon->mhp -= dam) <= 0) {
  2409.             int xx = mon->mx;
  2410.             int yy = mon->my;
  2411.  
  2412.             monkilled(mon, "", AD_PHYS);
  2413.             newsym(xx, yy);
  2414.             trapkilled = TRUE;
  2415.         }
  2416.     }
  2417.     if (obj && (!strike || d_override)) {
  2418.         place_object(obj, mon->mx, mon->my);
  2419.         obj->nobj = fobj;
  2420.         fobj = obj;
  2421.         stackobj(fobj);
  2422.     } else if (obj) dealloc_obj(obj);
  2423.  
  2424.     return trapkilled;
  2425. }
  2426.  
  2427. boolean
  2428. unconscious()
  2429. {
  2430.     return (multi < 0 && (!nomovemsg ||
  2431.         u.usleep ||
  2432.         !strncmp(nomovemsg,"You regain con", 15) ||
  2433.         !strncmp(nomovemsg,"You are consci", 15)));
  2434. }
  2435.  
  2436. static char lava_killer[] = "molten lava";
  2437.  
  2438. boolean
  2439. lava_effects()
  2440. {
  2441.     register struct obj *obj, *obj2;
  2442.     int dmg;
  2443.  
  2444.     if (!Fire_resistance) {
  2445.     if(Wwalking) {
  2446.         dmg = d(6,6);
  2447.         pline("The lava here burns you!");
  2448.         if(dmg < u.uhp) {
  2449.         losehp(dmg, lava_killer, KILLED_BY);
  2450.         goto burn_stuff;
  2451.         }
  2452.     } else
  2453.         You("fall into the lava!");
  2454.  
  2455.     for(obj = invent; obj; obj = obj2) {
  2456.         obj2 = obj->nobj;
  2457.         if(is_organic(obj) && !obj->oerodeproof) {
  2458.         if(obj->owornmask) {
  2459.             if(obj == uarm) (void) Armor_gone();
  2460.             else if(obj == uarmc) (void) Cloak_off();
  2461.             else if(obj == uarmh) (void) Helmet_off();
  2462.             else if(obj == uarms) (void) Shield_off();
  2463.             else if(obj == uarmg) (void) Gloves_off();
  2464.             else if(obj == uarmf) (void) Boots_off();
  2465. #ifdef TOURIST
  2466.             else if(obj == uarmu) setnotworn(obj);
  2467. #endif
  2468.             else if(obj == uleft) Ring_gone(obj);
  2469.             else if(obj == uright) Ring_gone(obj);
  2470.             else if(obj == ublindf) Blindf_off(obj);
  2471.             else if(obj == uwep) uwepgone();
  2472.             if(Lifesaved
  2473. #ifdef WIZARD
  2474.                || wizard
  2475. #endif
  2476.                ) Your("%s into flame!", aobjnam(obj, "burst"));
  2477.         }
  2478.         useup(obj);
  2479.         }
  2480.     }
  2481.  
  2482.     /* s/he died... */
  2483.     u.uhp = -1;
  2484.     killer_format = KILLED_BY;
  2485.     killer = lava_killer;
  2486.     You("burn to a crisp...");
  2487.     done(BURNING);
  2488.     if (!safe_teleds())
  2489.         while (1) {
  2490.             pline("You're still burning.");
  2491.             done(BURNING);
  2492.         }
  2493.     You("find yourself back on solid ground.");
  2494.     return(TRUE);
  2495.     }
  2496.  
  2497.     if (!Wwalking) {
  2498.     u.utrap = rn1(4, 4) + (rn1(4, 12) << 8);
  2499.     u.utraptype = TT_LAVA;
  2500.     You("sink into the lava, but it doesn't burn you!");
  2501.     }
  2502.     /* just want to burn boots, not all armor; destroy_item doesn't work on
  2503.        armor anyway */
  2504. burn_stuff:
  2505.     if(uarmf && !uarmf->oerodeproof && is_organic(uarmf)) {
  2506.     /* save uarmf value because Boots_off() sets uarmf to NULL */
  2507.     obj = uarmf;
  2508.     Your("%s burst into flame!", xname(obj));
  2509.     (void) Boots_off();
  2510.     useup(obj);
  2511.     }
  2512.     destroy_item(SCROLL_CLASS, AD_FIRE);
  2513.     destroy_item(SPBOOK_CLASS, AD_FIRE);
  2514.     destroy_item(POTION_CLASS, AD_FIRE);
  2515.     return(FALSE);
  2516. }
  2517.  
  2518. #endif /* OVLB */
  2519.  
  2520. /*trap.c*/
  2521.